if(CHIP STREQUAL "ws53")
    include (${WIFI_DIR}/wifi_alg_ws53.cmake)
    add_subdirectory(${WIFI_DIR}/source/alg wifi_alg)
elseif(CHIP STREQUAL "ws63")
    if(DEFINED LLT_PATH)
        include (${WIFI_DIR}/wifi_alg_ws63.cmake)
        add_subdirectory(${WIFI_DIR}/source/alg wifi_alg)
    endif()
elseif(DEFINED CHIP)
    return()
else()
    set(project_name ws73)
    add_subdirectory(${WIFI_DIR}/source/alg wifi_alg)
    include (${WIFI_DIR}/wifi_alg_ws73.cmake)
endif()

function(wifi_alg_addprefix prefix list_name)
    set(${list_name}_tmp)
    foreach(component IN LISTS ${list_name})
        list(APPEND ${list_name}_tmp ${prefix}${component})
    endforeach()
    set(${list_name} ${${list_name}_tmp} PARENT_SCOPE)
    unset(${list_name}_tmp)
endfunction()

function(wifi_alg_add_components _in_components)
    set(_out_components)
    if(${_in_components})
        foreach(component IN LISTS ${_in_components})
            get_property(${component} GLOBAL PROPERTY ${component})
            set(temp_component ${${component}})
            if(${component})
                if(MY_ADD_DEFINES_PREFIX AND component MATCHES ".*DEFINES")
                    wifi_alg_addprefix("-D" ${component})
                endif()
                list(APPEND _out_components ${${component}})
            endif()
        endforeach()
    endif()
    set(_out_components ${_out_components} PARENT_SCOPE)
endfunction()

function(wifi_alg_add_ind_components out_components_final independent_components)
    foreach(ind_property IN LISTS ${independent_components})
        get_property(${ind_property} GLOBAL PROPERTY ${ind_property})
        set(ind_components ${${ind_property}})
        foreach(ind_component IN LISTS ind_components)
            string(TOUPPER ${ind_component} ind_component_upper)
            get_property(${ind_component_upper} GLOBAL PROPERTY ${ind_component_upper})
            list(APPEND ${out_components_final} ${${ind_component_upper}})
            endforeach()
    endforeach()
    set(_out_components ${${out_components_final}} PARENT_SCOPE)
endfunction()

function(wifi_alg_compiler_entry _component_name)
    set(options ADD_DEFINES_PREFIX)
    set(oneValueArgs OUT_SOURCES OUT_INCLUDES OUT_DEFINES)
    set(multiValueArgs WIFI_SOURCES WIFI_INCLUDES WIFI_DEFINES ALG_INDEPENDENT)
    cmake_parse_arguments(MY "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    if(${_component_name})
        cmake_parse_arguments(${project_name} "" "" "${multiValueArgs}" ${${_component_name}})
        wifi_alg_add_components("${project_name}_WIFI_SOURCES")
        if (MY_ALG_INDEPENDENT)
            set(independent_components MY_ALG_INDEPENDENT)
            set(out_components_final _out_components)
            wifi_alg_add_ind_components(${out_components_final} ${independent_components})
        endif()
        list(APPEND MY_WIFI_SOURCES ${_out_components})
        wifi_alg_add_components("${project_name}_WIFI_INCLUDES")
        list(APPEND MY_WIFI_INCLUDES ${_out_components})
        wifi_alg_add_components("${project_name}_WIFI_DEFINES")
        list(APPEND MY_WIFI_DEFINES ${_out_components})
    else()
        message(ERROR "unknown wifi alg componet name")
    endif()
    if(MY_OUT_SOURCES)
        set(${MY_OUT_SOURCES} "${MY_WIFI_SOURCES}" PARENT_SCOPE)
    endif()
    if(MY_OUT_DEFINES)
        set(${MY_OUT_DEFINES} "${MY_WIFI_DEFINES}" PARENT_SCOPE)
    endif()
    if(MY_OUT_INCLUDES)
        set(${MY_OUT_INCLUDES} "${MY_WIFI_INCLUDES}" PARENT_SCOPE)
    endif()
endfunction()

function(wifi_alg_build_ind_component component)
    set(COMPONENT_NAME ${component})
    string(TOUPPER ${component} component_upper)
    set(SOURCES)
    get_property(${component_upper} GLOBAL PROPERTY ${component_upper})
    foreach(source IN LISTS ${component_upper})
        list(APPEND SOURCES ${source})
    endforeach()
    add_base_config()
    build_component()
endfunction()

function(wifi_alg_independent_build ind_components)
    foreach(ind_component IN LISTS ${ind_components})
        get_property(${ind_component} GLOBAL PROPERTY ${ind_component})
        foreach(ind IN LISTS ${ind_component})
            wifi_alg_build_ind_component(${ind})
        endforeach()
    endforeach()
endfunction()

function(wifi_alg_copy_src)
    execute_process(COMMAND "rm" "-rf" "alg_src" COMMAND "mkdir" "-p" "alg_src/device" COMMAND "mkdir" "-p" "alg_src/host")
    set(files WIFI_ALG_COMMON_DEVICE_ROM_SOURCES WIFI_ALG_COMMON_DEVICE_RAM_SOURCES WIFI_ALG_IOT_DEVICE_ROM_SOURCES
        WIFI_ALG_IOT_DEVICE_RAM_SOURCES WIFI_ALG_IOT_DEVICE_IND_SOURCES WIFI_ALG_COMMON_HOST_SOURCES WIFI_ALG_IOT_HOST_SOURCES)
    set(ind_files  WIFI_ALG_IOT_HOST_IND_SOURCES WIFI_ALG_IOT_DEVICE_IND_SOURCES)
    foreach(ind_component IN LISTS files)
        get_property(${ind_component} GLOBAL PROPERTY ${ind_component})
        foreach(ind IN LISTS ${ind_component})
            if(ind_component MATCHES ".*DEVICE.*")
                execute_process(COMMAND "cp" ${ind} "./alg_src/device/")
            else()
                execute_process(COMMAND "cp" ${ind} "./alg_src/host/")
            endif()
        endforeach()
    endforeach()
    foreach(ind_component IN LISTS ind_files)
        get_property(${ind_component} GLOBAL PROPERTY ${ind_component})
        foreach(ind IN LISTS ${ind_component})
            string(TOUPPER ${ind} ind_upper)
            get_property(ind2 GLOBAL PROPERTY ${ind_upper})
            foreach(source IN LISTS ind2)
                if(ind_component MATCHES ".*DEVICE.*")
                    execute_process(COMMAND "cp" ${source} "./alg_src/device/")
                else()
                    execute_process(COMMAND "cp" ${source} "./alg_src/host/")
                endif()
            endforeach()
        endforeach()
    endforeach()
endfunction()